package ltd.dujiabao.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

/**
 * @author : DuJiabao
 * @Project : io_test
 * @Time : 2021/5/30 20:32
 * @Desc :
 */
public class Server {
  public static void main(String[] args) throws IOException {
    ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); // socket服务端专门的通道，开启
    serverSocketChannel.configureBlocking(false);  // 开启非阻塞模式
    serverSocketChannel.bind(new InetSocketAddress(8888)); // 绑定端口号
    Selector selector = Selector.open();  // 开启一个新的选择器
    serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); // 将socket处理连接的通道也绑定到选择器中，并选择为接收模式
    System.out.println("开启了");

    // 进入轮询状态
    while (selector.select() > 0) {  // 当通道大于0
      Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
      while (iterator.hasNext()) {  // 如果有任务来了就进行，否则就阻塞
        System.out.println("有任务来了");
        SelectionKey selectionKey = iterator.next();
        if (selectionKey.isAcceptable()) {  // 如果是请求连接任务来了
          System.out.println("有新的连接过来了");
          SocketChannel newChannel = serverSocketChannel.accept(); // 终究还是要接收的，只是现在才进入接收请求
          newChannel.configureBlocking(false);// 开启非阻塞模式
          newChannel.register(selector, SelectionKey.OP_READ); // 将这个新通道放进选择器中
        } else if (selectionKey.isReadable()) {  // 如果是写任务来了
          System.out.println("有新的数据来了");
          SocketChannel channel = (SocketChannel) selectionKey.channel(); // 将里面的通道拿出来
          // 开始基本的读操作
          ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
          while (channel.read(byteBuffer) > 0) {
            byteBuffer.flip();
            System.out.println(new String(byteBuffer.array(), 0, byteBuffer.remaining()));
            byteBuffer.clear();
          }
        }
        // 处理完之后还要删了它
        iterator.remove();
      }
    }
    // 任务结束
    serverSocketChannel.close();
    selector.close();
  }
}
